package com.bjpowernode.money.service.impl;

import com.alibaba.dubbo.config.annotation.Service;
import com.bjpowernode.money.constant.BidRankListConstant;
import com.bjpowernode.money.constant.IndexConstant;
import com.bjpowernode.money.mapper.BidInfoMapper;
import com.bjpowernode.money.mapper.LoanInfoMapper;
import com.bjpowernode.money.model.BidInfo;
import com.bjpowernode.money.model.LoanInfo;
import com.bjpowernode.money.model.PageModel;
import com.bjpowernode.money.service.LoanInfoService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import org.springframework.stereotype.Component;

import java.time.Duration;
import java.util.HashMap;
import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;

/**
 * @author ZHAOZHENYU
 * @since 2022/10/14
 */
@Service(interfaceClass = LoanInfoService.class, version = "1.0.0", timeout = 20000)
@Component
public class LoanInfoServiceImpl implements LoanInfoService {

    @Autowired(required = false)
    private RedisTemplate redisTemplate;

    @Autowired(required = false)
    private LoanInfoMapper loanInfoMapper;

    @Autowired
    private BidInfoMapper bidInfoMapper;

    @Override
    public Double queryLoanRateAvg() {
        redisTemplate.setKeySerializer(new StringRedisSerializer());
        Double loanRateAvg = (Double) redisTemplate.opsForValue().get(IndexConstant.LOAN_RATE_AVG);
        if (loanRateAvg == null){
            synchronized (this) {
                // 再查一次是否已经放进redis
                loanRateAvg = (Double) redisTemplate.opsForValue().get(IndexConstant.LOAN_RATE_AVG);
                if (loanRateAvg == null) {
                    loanRateAvg = loanInfoMapper.selectLoanRateAvg();
                }
                redisTemplate.opsForValue().set(IndexConstant.LOAN_RATE_AVG, loanRateAvg, 5, TimeUnit.MINUTES);
            }
        }
        return loanRateAvg;
    }

    @Override
    public List<LoanInfo> queryLoanProduct(HashMap<String, Object> paramsMap) {
        return loanInfoMapper.selectLoanProduct(paramsMap);
    }

    @Override
    public List<LoanInfo> queryLoanProductPage(Integer pType, PageModel pageModel) {

        Integer pageSize = pageModel.getPageSize();
        Long currentPage = pageModel.getCurrentPage();
        HashMap<String, Object> paramsMap = new HashMap<>();
        paramsMap.put("pType", pType);
        paramsMap.put("start", (currentPage - 1) * pageSize);
        paramsMap.put("content", pageSize);
        return loanInfoMapper.selectLoanProduct(paramsMap);

    }

    @Override
    public Long queryLoanCountByType(Integer pType) {
        return loanInfoMapper.selectLoanCountByType(pType);
    }

    @Override
    public LoanInfo queryLoanInfoById(Integer loanId) {
        return loanInfoMapper.selectByPrimaryKey(loanId);
    }

    @Override
    public List<BidInfo> queryBidRankList() {

        redisTemplate.setKeySerializer(new StringRedisSerializer());

        Set idSet = redisTemplate.opsForZSet().reverseRange(BidRankListConstant.BID_RANK_LIST, 0, 4);

        // redis没有数据时，主业务直接查数据库
        if (idSet.size() == 0){
            synchronized (this) {
                idSet = redisTemplate.opsForZSet().reverseRange(BidRankListConstant.BID_RANK_LIST, 0, 4);
                if (idSet.size() == 0) {
                    System.out.println("*********排行榜查询数据库************");
                    // 查出所有投资记录
                    List<BidInfo> bidInfoList = bidInfoMapper.selectAllBidInfo();
                    // 遍历后返给redis
                    for (BidInfo bidInfo : bidInfoList) {
                        // zSet将id按照投资金额排名存入redis
                        redisTemplate.opsForZSet().add(BidRankListConstant.BID_RANK_LIST, bidInfo.getId(), bidInfo.getBidMoney());
                        redisTemplate.expire(BidRankListConstant.BID_RANK_LIST, Duration.ofHours(1));
                    }
                    idSet = redisTemplate.opsForZSet().reverseRange(BidRankListConstant.BID_RANK_LIST, 0, 4);
                }
            }
        }

        // 查出前5个投资记录
        List<BidInfo> bidInfoList = bidInfoMapper.selectBidInfoByIdForRank(idSet);

        return bidInfoList;

    }
}
